本篇文章同步發表在 HKT 線上教室 部落格,線上影音教學課程已上架至 Udemy 和 Youtube 頻道。另外,想追蹤更多相關技術資訊,歡迎到 臉書粉絲專頁 按讚追蹤喔~
範例名稱:獲取位置權限
開發人員:HKT (侯光燦)
程式語言:Kotlin
開發環境:Android Studio 4.1.2 & Android 11 & Kotlin 1.4.30
授權範圍:使用時必須註明出處且不得為商業目的之使用
範例下載點:點我下載
在之前的介紹當中,我們主要的重心是放在,如何在滾動式列表上呈現藥局資訊。而在接下來的重心,我們將會放在,如何在 Google Map 地圖上,呈現藥局地點與藥局相關資訊。將會依序的跟大家介紹:
所以今天要先來跟大家介紹第一個部分,如何獲取使用者位置權限,除了要在 AndroidManifest.xml 宣告外,因為「位置權限」被列屬為危險權限,從 Android 6 (SDK 23)以上,需要特別額外跟使用詢問獲取,否則會因權限不足,而造成 APP 閃退。詳細權限級別,可以查閱官網文件: Manifest.permission。
獲取 APP 權限,主要分成這四個部分。
檢查我們的APP,是否獲得權限
是否要顯示更多說明解釋為何此權限對話視窗。收到 true,代表需要跟使用者顯示更多說明解釋為何此權限對話視窗,收到 false,代表不需額外顯示給使用者說明。
要求用戶給我們APP使用權限
覆寫此方法,要求權限後,會收到用戶決定是否給權限的結果 CallBack
獲取位置權限,需要先在 AndroidManifest.xml 裡,加入此宣告。位置權限有兩種,一個是概略位置存取權(ACCESS_COARSE_LOCATION)和另一個精確位置存取(ACCESS_FINE_LOCATION),擇一即可,我們選擇精確定位權限。
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
我們先新開一個空白的 Activity 頁面,檔名為 MapActivity,並在 AndroidManifest.xml 裡將啟動載入Activity,更改為此 Activity。
<activity android:name=".MapActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
透過 checkSelfPermission 方法,檢查有無精準位置(ACCESS_FINE_LOCATION)權限,若沒有則詢問使用者要求獲取權限,若獲得 locationPermissionGranted 設定為 true。
private var locationPermissionGranted = false
...
...
...
private fun getLocationPermission() {
//檢查權限
if (ActivityCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED
) {
//已獲取到權限
Toast.makeText(this, "已獲取到位置權限,可以準備開始獲取經緯度", Toast.LENGTH_SHORT).show()
locationPermissionGranted = true
//todo checkGPSState()
} else {
//詢問要求獲取權限
requestLocationPermission()
}
}
private fun requestLocationPermission() {
if (ActivityCompat.shouldShowRequestPermissionRationale(
this, Manifest.permission.ACCESS_FINE_LOCATION
)
) {
AlertDialog.Builder(this)
.setMessage("此應用程式,需要位置權限才能正常使用")
.setPositiveButton("確定") { _, _ ->
ActivityCompat.requestPermissions(
this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
REQUEST_LOCATION_PERMISSION
)
}
.setNegativeButton("取消") { _, _ -> requestLocationPermission() }
.show()
} else {
ActivityCompat.requestPermissions(
this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), REQUEST_LOCATION_PERMISSION
)
}
}
override fun onRequestPermissionsResult(
requestCode: Int, permissions: Array<out String>, grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when (requestCode) {
REQUEST_LOCATION_PERMISSION -> {
if (grantResults.isNotEmpty()) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//已獲取到權限
locationPermissionGranted = true
//todo checkGPSState()
} else if (grantResults[0] == PackageManager.PERMISSION_DENIED) {
if (!ActivityCompat.shouldShowRequestPermissionRationale(
this,
Manifest.permission.ACCESS_FINE_LOCATION
)
) {
//權限被永久拒絕
Toast.makeText(this, "位置權限已被關閉,功能將會無法正常使用", Toast.LENGTH_SHORT).show()
AlertDialog.Builder(this)
.setTitle("開啟位置權限")
.setMessage("此應用程式,位置權限已被關閉,需開啟才能正常使用")
.setPositiveButton("確定") { _, _ ->
val intent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
startActivityForResult(intent, REQUEST_LOCATION_PERMISSION)
}
.setNegativeButton("取消") { _, _ -> requestLocationPermission() }
.show()
} else {
//權限被拒絕
Toast.makeText(this, "位置權限被拒絕,功能將會無法正常使用", Toast.LENGTH_SHORT).show()
requestLocationPermission()
}
}
}
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
REQUEST_LOCATION_PERMISSION -> {
getLocationPermission()
}
}
}
第一次呈現詢問畫面
若在第一次詢問,選擇「拒絕」,則會出現,我們自定義的對話視窗,可以在這個視窗跟用戶說明為何需要權限。
若是選擇「拒絕且不在詢問」,將不會在出現詢問視窗
HKT 線上教室
https://tw-hkt.blogspot.com/
Freepik
https://www.freepik.com/
Build location-aware apps
https://developer.android.com/training/location
Request App Permissions
https://developer.android.com/training/permissions/requesting
permissions API reference page
https://developer.android.com/reference/android/Manifest.permission#ACCESS_FINE_LOCATION
Location Data
https://developers.google.com/maps/documentation/android-sdk/location
Select Current Place and Show Details on a Map
https://developers.google.com/maps/documentation/android-sdk/current-place-tutorial
那今天【iThome 鐵人賽】就介紹到這邊囉~
順帶一提,KT 線上教室,臉書粉絲團,會不定期發佈相關資訊,不想錯過最新資訊,不要忘記來按讚,追蹤喔!也歡迎大家將這篇文章分享給更多人喔。
我們明天再見囉!!!掰掰~